home *** CD-ROM | disk | FTP | other *** search
/ BMUG Revelations / BMUG Revelations.toast / Utilities / Random / Commodore 64c / SOURCE / Memory.c < prev    next >
Text File  |  1994-03-19  |  6KB  |  207 lines

  1. /*
  2.     Commodore 64 Emulator v0.2      Earle F. Philhower III 
  3.     Copyright (C) 1993-4            (st916w9r@dunx1.ocs.drexel.edu)
  4.  
  5.     This program is free software; you can redistribute it and/or modify
  6.     it under the terms of the GNU General Public License as published by
  7.     the Free Software Foundation; either version 2 of the License, or
  8.     (at your option) any later version.
  9.  
  10.     This program is distributed in the hope that it will be useful,
  11.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.     GNU General Public License for more details.
  14.  
  15.     You should have received a copy of the GNU General Public License
  16.     along with this program; if not, write to the Free Software
  17.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18. */
  19. #include "Error.h"
  20. #include "Memory.h"
  21. #include "MemoryCalls.h"
  22.  
  23. /*
  24.     Uncomment the following line to speed up the KERNEL reset routine by
  25.     short-circuiting the RAM test.  No other changes are made.
  26. */
  27. #define MODROM
  28.  
  29. /* Global memory pointers */
  30. byte *RAM=nil, *loROM=nil, *hiROM=nil, *charROM=nil;
  31. byte *RAMp1=nil, *loROMp1=nil, *hiROMp1=nil, *charROMp1=nil;
  32. byte **memory=nil, **memoryp1=nil;
  33.  
  34. /* Used for the memory mapping routines locally */
  35. static byte **loRAMstore=nil, **loROMstore=nil;
  36. static byte **hiRAMstore=nil, **hiROMstore=nil;
  37. static byte **charRAMstore=nil, **charROMstore=nil;
  38.  
  39.  
  40. int MemoryInitialize(void)
  41. {
  42.     Handle temp;
  43.     word x;
  44.     
  45.     /* Get space for RAM and ROMS */
  46.     RAM=(byte *)GetMemory(0x10001);
  47.     loROM=(byte *)GetMemory(0x2000);
  48.     charROM=(byte *)GetMemory(0x1000);
  49.     hiROM=(byte *)GetMemory(0x2000);
  50.     if ((RAM==nil)||(loROM==nil)||(charROM==nil)||(hiROM==nil))
  51.         return(kOutOfMemory);
  52.     
  53.     /* Load the ROMS into the memory allocated */
  54.     temp=GetResource('ROMS', 128);    /* BASIC */
  55.     if (temp==nil) return(kROMMissing);
  56.     BlockMove(*temp, loROM, 0x2000);
  57.     ReleaseResource(temp);
  58.     
  59.     temp=GetResource('ROMS', 129);    /* CHARACTERS */
  60.     if (temp==nil) return(kROMMissing);
  61.     BlockMove(*temp, charROM, 0x1000);
  62.     ReleaseResource(temp);
  63.     
  64.     temp=GetResource('ROMS', 130);    /* KERNAL */
  65.     if (temp==nil) return(kROMMissing);
  66.     BlockMove(*temp, hiROM, 0x2000);
  67.     ReleaseResource(temp);
  68.  
  69. #ifdef MODROM
  70.     /* Start RAM test at 0x9d00 instead of 0x0400 */
  71.     hiROM[0x1d69]=0x9d;
  72. #endif
  73.     
  74.     /* Set up the hi-byte shortcut pointers */
  75.     RAMp1=&RAM[1];
  76.     loROMp1=&loROM[1];
  77.     charROMp1=&charROM[1];
  78.     hiROMp1=&hiROM[1];
  79.     
  80.     /* Get the double-dereference memory map space */
  81.     memory=(byte**)GetMemory(0x10001*sizeof(byte *));
  82.     if (memory!=nil) memoryp1=&(memory[1]);
  83.     loRAMstore=(byte**)GetMemory(0x2000*sizeof(byte *));
  84.     loROMstore=(byte**)GetMemory(0x2000*sizeof(byte *));
  85.     charRAMstore=(byte**)GetMemory(0x1000*sizeof(byte *));
  86.     charROMstore=(byte**)GetMemory(0x1000*sizeof(byte *));
  87.     hiRAMstore=(byte**)GetMemory(0x2000*sizeof(byte *));
  88.     hiROMstore=(byte**)GetMemory(0x2000*sizeof(byte *));
  89.     if ((loRAMstore==nil)||(loROMstore==nil)||(charRAMstore==nil)||
  90.         (charROMstore==nil)||(hiRAMstore==nil)||(hiROMstore==nil)||
  91.         (memory==nil))
  92.         return(kOutOfMemory);
  93.     
  94.     /* Set up the standard RAM pointers into our memory[] */
  95.     for (x=0x0000; x<0xffff; x++) memory[x]=&RAM[x];
  96.     memory[x]=&(RAM[x]);    /* Takes care of overflow */
  97.  
  98.     /* Copy the ROM and RAM pointers into our holding places */
  99.     for (x=0x0000; x<0x2000; x++) {
  100.         loROMstore[x]=&loROM[x];
  101.         loRAMstore[x]=&(RAM[0xa000+x]); }
  102.     for (x=0x0000; x<0x1000; x++) {
  103.         charROMstore[x]=&charROM[x];
  104.         charRAMstore[x]=&(RAM[0xd000+x]); }
  105.     for (x=0x0000; x<0x2000; x++) {
  106.         hiROMstore[x]=&hiROM[x];
  107.         hiRAMstore[x]=&(RAM[0xe000+x]); }
  108.     
  109.     return(kNoError);
  110. }
  111.  
  112. void MemoryCleanUp(void)
  113. {
  114.     if (RAM != nil) FreeMemory(RAM);
  115.     if (loROM != nil) FreeMemory(loROM);
  116.     if (charROM != nil) FreeMemory(charROM);
  117.     if (hiROM != nil) FreeMemory(hiROM);
  118.     if (memory != nil) FreeMemory(memory);
  119.     if (loRAMstore != nil) FreeMemory(loRAMstore);
  120.     if (loROMstore != nil) FreeMemory(loROMstore);
  121.     if (charRAMstore != nil) FreeMemory(charRAMstore);
  122.     if (charROMstore != nil) FreeMemory(charROMstore);
  123.     if (hiRAMstore != nil) FreeMemory(hiRAMstore);
  124.     if (hiROMstore != nil) FreeMemory(hiROMstore);
  125. }
  126.  
  127. void SetUpMemoryMap(void)
  128. {
  129.     if (*RAMp1&(1<<0)) BlockMove(loROMstore, &memory[0xa000],(0x2000*sizeof(byte *)));
  130.     else BlockMove(loRAMstore, &memory[0xa000],(0x2000*sizeof(byte *)));
  131.  
  132.     if (*RAMp1&(1<<1)) BlockMove(charRAMstore, &memory[0xd000],(0x1000*sizeof(byte *)));
  133.     else BlockMove(charROMstore, &memory[0xd000],(0x1000*sizeof(byte *)));
  134.  
  135.     if (*RAMp1&(1<<2)) BlockMove(hiROMstore, &memory[0xe000],(0x2000*sizeof(byte *)));
  136.     else BlockMove(hiRAMstore, &memory[0xe000],(0x2000*sizeof(byte *)));
  137.  
  138.     CheckMemory();
  139. }
  140.  
  141.  
  142. #define SIGNATURE 'BoMb'
  143. #define MAXSLOTS 64
  144. typedef unsigned long SignatureType;
  145. typedef struct {
  146.     byte *startOfMem, *givenMemPtr;
  147.     SignatureType id;
  148. } Signature;
  149. static Signature signature[MAXSLOTS];
  150. static byte numSignatures=0;
  151.  
  152. byte *GetMemory(unsigned long size)
  153. {
  154.     byte *mem;
  155.     
  156.     /* First see if we've got room in our memory pointers */
  157.     if (numSignatures==MAXSLOTS) InternalError(kOutOfMemoryPointers);
  158.     
  159.     /* Get memory from heap, including space for our signature */
  160.     mem=(byte *)NewPtrClear(size+sizeof(SignatureType));
  161.     if (mem==nil) return (byte *)nil;
  162.     
  163.     /* Set up our memory structure */
  164.     signature[numSignatures].startOfMem=mem;
  165.     signature[numSignatures].givenMemPtr=&(mem[sizeof(SignatureType)]);
  166.     signature[numSignatures].id=SIGNATURE;
  167.     
  168.     /* Store out "sentinel" bytes that SHOULD NOT BE OVERWRITTEN */
  169.     BlockMove(&(signature[numSignatures].id), mem, sizeof(SignatureType));
  170.     
  171.     /* Return address just after out sentinel */
  172.     return signature[numSignatures++].givenMemPtr;
  173. }
  174.  
  175. void FreeMemory(void *mem)
  176. {
  177.     int x, y;
  178.     byte *memory=(byte *)mem;
  179.     
  180.     /* Search for the passed memory pointer in the list of ones we've given */
  181.     for (x=0; x<numSignatures; x++)
  182.         if (memory==signature[x].givenMemPtr)
  183.         {
  184.             /* Found a match, free the memory */
  185.             DisposePtr((Ptr)signature[x].startOfMem);
  186.             /* Shift out pointers down to fill the vacant slot */
  187.             for (y=x; y<numSignatures; y++) signature[y]=signature[y+1];
  188.             numSignatures--;
  189.             return;
  190.         }
  191.     /* Didn't find the memory, so exit gracefully */
  192.     InternalError(kInvalidMemoryFree);
  193. }
  194.  
  195. void CheckMemory(void)
  196. {
  197.     int x;
  198.     SignatureType sign;
  199.     
  200.     /* Scan all of out given signatures for the sentinel value */
  201.     for (x=0; x<numSignatures; x++)
  202.     {
  203.         sign=*(SignatureType *)signature[x].startOfMem;
  204.         if (sign!=signature[x].id) InternalError(kMemoryViolation);
  205.     }
  206. }
  207.